import getIn from './getIn';
import _dispatch from './dispatch';
/**
 * 方法调度器（ActionDispatcher），统一调用接口方法的控制器，通过excute去调用不同的接口类。
 * @param core 核心类，必须设置好apiBase和domain[必填]
 * @param commonFetch 访问网络的方法，分开wx端和app端[必填]
 * @param dispatch 方法链，在执行每个方法后必触发的方法。一般可设置redux或者自定义日志链[可选]
 * @param optionParams 附加的参数列表，可以传入一些额外的参数到接口中
 * @constructor
 */
import { success, SUCCESS } from './success';
import { start, START } from './start';
import { fail, FAIL } from './fail';
import { checkLogin } from './wxLogin';
function wxAssemblyFetch(action, url, params, extra = {}, callback) {
  return (dispatch) => {
    if (!action) return;
    // dispatch(start(action, { params, fetchResult: {}, ...extra }));
    callback && callback(START);
    wx.request({
      url,
      data: JSON.stringify(params),
      method: 'POST',
      success(response = {}) {
        const fetchResult = response.data;
        if (fetchResult && fetchResult.code > 0) {
          // dispatch(success(action, { params, fetchResult, ...extra }));
          callback && callback(SUCCESS, fetchResult);
        } else if (fetchResult && (fetchResult.code === -13002 || fetchResult.code === -11406 || fetchResult.code === -13001)) {
          // dispatch(fail(action, { params, fetchResult: {}, ...extra }));
          callback && callback(FAIL, fetchResult);
          // token或者domain缺失或者登录异常
          checkLogin && checkLogin((callback) => { });
        } else {
          // dispatch(fail(action, { params, fetchResult: {}, ...extra }));
          callback && callback(FAIL, fetchResult);
        }
      },
      fail(response = {}) {
        const fetchResult = response.data;
        callback && callback(FAIL, fetchResult);
      },
    });
  };
}

export default function ActionDispatcher(core, dispatch = _dispatch, optionParams) {
  if (!core) {
    console.error('need core');
    return;
  }
  this.commonFetch = wxAssemblyFetch;
  this.core = core;
  this.dispatch = dispatch;
  /**
   * 接口类的url一般是部分地址，拼接真实的api地址
   * @param url
   */
  this.getUrl = url => `${getIn(this, ['core', 'apiBase'])}${url}`
  /**
   * 检测是否传入domain变量
   * @param params
   * @returns {{}}
   */
  this.getParams = (params = {}) => {
    if (params.toJS) params = params.toJS();
    if (!params.domain) params.domain = getIn(this, ['core', 'domain']);
    if (optionParams) params = { ...optionParams, ...params };
    return params;
  };
  /**
   * 执行接口方法
   * @param actionClass 接口信息类
   * @param params 参数集
   * @param callback 回调
   * @param extra 额外数据（不经过接口，提供额外的操作。reducer可用）
   */
  this.execute = (actionClass, params, callback, extra) => this.dispatch(this.commonFetch(actionClass.type, this.getUrl(actionClass.url), this.getParams(params), extra, callback));
}
